package com.hao.study.utils;

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.http.HttpHeaders;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author: author
 * @description:
 * @date: 2024/6/13 22:21
 * @version: 1.0
 */
public class HttpContextUtils {

    /**
     * 获取当前线程绑定的HttpServletRequest对象。
     * 该方法通过利用Spring框架的RequestContextHolder工具类，
     * 来获取当前执行的HTTP请求的HttpServletRequest对象。
     * 如果当前线程没有绑定HttpServletRequest对象，则返回null。
     *
     * @return 当前线程绑定的HttpServletRequest对象，如果不存在则返回null。
     */
    public static HttpServletRequest getHttpServletRequest(){
        // 通过RequestContextHolder获取当前请求的属性
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        // 判断请求属性是否为空，为空则表示当前线程没有绑定HttpServletRequest
        if (requestAttributes==null){
            return null;
        }
        // 将请求属性转为ServletRequestAttributes类型，并从中获取HttpServletRequest对象
        return ((ServletRequestAttributes)requestAttributes).getRequest();
    }


    /**
     * 获取HttpServletRequest中的参数映射。
     * 该方法通过遍历请求的所有参数名称，并获取对应的参数值，构建一个参数名到参数值的映射。
     * 参数值为空或只包含空格的情况将被忽略，不会添加到映射中。
     *
     * @param request HttpServletRequest对象，从中提取参数信息。
     * @return 一个Map，包含请求中的所有非空参数及其值。
     */
    public static Map<String,String> getParameterMap(HttpServletRequest request){
        // 获取请求中所有的参数名称
        Enumeration<String> parameters = request.getParameterNames();

        // 初始化一个映射，用于存储参数名和参数值
        Map<String,String> params = new HashMap<>();
        // 遍历所有参数名称
        while (parameters.hasMoreElements()){
            // 获取当前参数名称
            String parameter = parameters.nextElement();
            // 获取当前参数的值
            String value =request.getParameter(parameter);
            // 如果参数值不为空且不只包含空格，则将参数名和值添加到映射中
            if (StringUtils.isNotBlank(value)){
                params.put(parameter,value);
            }
        }
        // 返回构建好的参数映射
        return params;
    }

    /**
     * 获取当前请求的域名。
     * 该方法用于从HttpServletRequest中提取出当前请求的域名部分，不包括端口和路径信息。
     * 主要用于需要获取当前请求域名的场景，例如构建返回给客户端的完整URL。
     *
     * @return 当前请求的域名字符串。
     */
    public static String getDomain(){
        // 通过getHttpServletRequest方法获取当前请求的HttpServletRequest对象
        HttpServletRequest request = getHttpServletRequest();
        // 获取当前请求的完整URL
        StringBuffer url = request.getRequestURL();
        // 删除URL中的路径和查询参数部分，只保留域名
        // 通过request.getRequestURL().length()获取URL的长度，用于定位路径和查询参数的起始位置
        // 使用delete方法删除从当前长度到末尾的字符，实现截取域名的目的
        return url.delete(url.length()-request.getRequestURL().length(),url.length()).toString();
    }


    /**
     * 获取请求的来源地址。
     * 该方法用于获取当前HTTP请求的Origin头部信息，Origin头部字段用于跨源资源共享（CORS）请求中，
     * 表示请求来自哪个源站。这对于处理跨域请求的服务器端代码来说是很有用的，
     * 可以根据这个信息来决定是否允许该跨域请求。
     *
     * @return 返回当前HTTP请求的Origin头部值。如果请求中没有Origin头，或者无法获取HttpServletRequest对象，
     * 则可能返回null或者空字符串。具体的返回值取决于实现和请求的具体情况。
     */
    public static String getOrigin(){
        // 通过getHttpServletRequest方法获取当前的HttpServletRequest对象。
        HttpServletRequest request = getHttpServletRequest();
        // 返回请求头部中名为"Origin"的字段值。
        return request.getHeader(HttpHeaders.ORIGIN);
    }

}
